package com.lucifer.d.security.config;

import com.lucifer.d.security.boot.MenuOrmInitServer;
import com.lucifer.d.security.config.conditional.*;
import com.lucifer.d.security.data.accept.DataCompletionAspect;
import com.lucifer.d.security.data.config.DataCompletionConfig;
import com.lucifer.d.security.exception.handler.SecurityExceptionHandler;
import com.lucifer.d.security.model.SecurityConfigModel;
import com.lucifer.d.security.model.property.PermitProperty;
import com.lucifer.d.security.service.gateway.properties.BootConfigProperties;
import com.lucifer.d.security.service.gateway.properties.OwnRedisProperties;
import com.lucifer.d.security.service.local.aspect.AuthAspect;
import com.lucifer.d.security.service.local.aspect.SignAspect;
import com.lucifer.d.security.transfer.SignTransfer;
import com.lucifer.d.security.transfer.UserTransfer;
import com.lucifer.d.util.SpringUtil;
import com.lucifer.d.util.StringUtil;
import org.redisson.Redisson;
import org.redisson.api.RedissonClient;
import org.redisson.config.Config;
import org.redisson.config.SingleServerConfig;
import org.springframework.boot.autoconfigure.condition.ConditionalOnMissingBean;
import org.springframework.boot.context.properties.EnableConfigurationProperties;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Conditional;
import org.springframework.context.annotation.Configuration;
import org.springframework.context.annotation.Primary;

import java.util.List;

/**
 * @author Lucifer
 * @create 2023 - 03 - 31 11:11
 */
@Configuration
@EnableConfigurationProperties({BootConfigProperties.class, SecurityConfigModel.class, OwnRedisProperties.class, PermitProperty.class})
public class LuciferSecurityConfiguration {

    /**
     * 自动装配配置注入
     * @return
     */
    @Conditional(OnSecurityCondition.class)
    @Bean
    @ConditionalOnMissingBean
    public DataCompletionConfig dataCompletionConfig(){
        return new DataCompletionConfig();
    }

    /**
     * 自动装配切面注入
     *
     * @return
     */
    @Conditional(OnSecurityCondition.class)
    @Bean
    public DataCompletionAspect dataCompletionAspect(){
        return new DataCompletionAspect();
    }

    /**
     * 用户黑盒工厂注入
     *
     * @return
     */
    @Conditional(OnSecurityCondition.class)
    @Bean
    @ConditionalOnMissingBean
    public UserTransfer userTransfer(SecurityConfigModel securityConfigModel){
        return new UserTransfer(securityConfigModel);
    }

    /**
     * 特殊过滤黑盒工厂注入
     *
     * @return
     */
    @Conditional(OnSecurityCondition.class)
    @Bean
    @ConditionalOnMissingBean
    public SignTransfer signTransfer(SecurityConfigModel securityConfigModel){
        return new SignTransfer(securityConfigModel);
    }

    /**
     * 独立Redis注册中心连接切换
     *
     * @param ownRedisProperties
     * @return
     */
    @Conditional({OnSecurityCondition.class, RedissonCondition.class})
    @Bean(destroyMethod="shutdown")
    @Primary
    public RedissonClient redissonClient(OwnRedisProperties ownRedisProperties) {
        // 创建配置 指定redis地址及节点信息
        Config config = new Config();
        SingleServerConfig singleServerConfig = config.useSingleServer();
        singleServerConfig
                .setAddress("redis://"+ownRedisProperties.getAddress() + ":"+ownRedisProperties.getPort())
                .setDatabase(ownRedisProperties.getClub());
        if (!StringUtil.isEmpty(ownRedisProperties.getPassword())){
            singleServerConfig.setPassword(ownRedisProperties.getPassword());
        }
        // 根据config创建出RedissonClient实例
        RedissonClient redissonClient = Redisson.create(config);
        return redissonClient;
    }

    /**
     * sign验证切面注入
     *
     * @return
     */
    @Conditional({OnSecurityCondition.class, SignCondition.class})
    @Bean
    public SignAspect signAspect(){
        return new SignAspect();
    }

    /**
     * 过滤业务切面注入
     *
     * @return
     */
    @Conditional({OnSecurityCondition.class, LocalSecurityCondition.class})
    @Bean
    public AuthAspect authAspect(){
        return new AuthAspect();
    }

    /**
     * 网关过滤服务配置注入
     *
     * @param bootConfigProperties
     * @return
     */
    @Conditional({OnSecurityCondition.class, GateWayCondition.class})
    @Bean
    public MenuOrmInitServer menuOrmInitServer(SecurityConfigModel securityConfigModel, BootConfigProperties bootConfigProperties){
        return new MenuOrmInitServer(securityConfigModel, bootConfigProperties);
    }

    /**
     * 异常处理器
     *
     * @return
     */
    @Conditional(OnSecurityCondition.class)
    @Bean
    public SecurityExceptionHandler securityExceptionHandler(){
        return new SecurityExceptionHandler();
    }

    @Bean
    public SpringUtil springUtil(){
        return new SpringUtil();
    }

}
